package com.gitee.feizns.quickstart.web.Interceptors.hmac;

import com.gitee.feizns.quickstart.web.ex.UnauthorizedException;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.lang.NonNull;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.Duration;
import java.util.function.Function;

/**
 * “Hash-based Message Authentication Code” 的缩写，中文通常叫
 * “基于哈希的消息认证码”。
 * @author feizns
 * @since 2025/10/17
 */
public class CaffeineHMACInterceptor extends HMACInterceptor {

    /**
     * 随机数缓存
     */
    private final Cache<String, Boolean> cache;

    /**
     * 拦截器
     * @param getAppSecret 获取应用密钥
     */
    public CaffeineHMACInterceptor(Function<String, String> getAppSecret) {
        this(getAppSecret, Duration.ofMinutes(15));
    }

    /**
     * 拦截器
     * @param getAppSecret 获取应用密钥
     */
    public CaffeineHMACInterceptor(Function<String, String> getAppSecret, Duration duration) {
        super(getAppSecret, duration);
        cache = Caffeine.newBuilder()
                .expireAfterWrite(duration)
                .build();
    }

    @Override
    public String getNonce() {
        String nonce = super.getNonce();
        if ( cache.getIfPresent(nonce) != null )
            throw new UnauthorizedException("请勿重复请求.");
        return nonce;
    }

    @Override
    public boolean preHandle(@NonNull HttpServletRequest request,
                             @NonNull HttpServletResponse response,
                             @NonNull Object handler) throws Exception {
        boolean result = super.preHandle(request, response, handler);
        cache.put(getNonce(), Boolean.TRUE);
        return result;
    }

}
